package world.xuewei.service;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import world.xuewei.dao.MedicineDao;
import world.xuewei.entity.Medicine;
import world.xuewei.entity.MedicineDoc;
import world.xuewei.utils.Assert;
import world.xuewei.utils.BeanUtil;
import world.xuewei.utils.VariableNameUtils;

import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * 药品服务类
 *
 *
 */
@Service
public class MedicineService extends BaseService<Medicine> {

    @Autowired
    protected MedicineDao medicineDao;
    @Autowired
    private EsService esService;
    @Autowired
    private RestHighLevelClient client;


    // 查询
    @Override
    public List<Medicine> query(Medicine o) {
        QueryWrapper<Medicine> wrapper = new QueryWrapper();
        if (Assert.notEmpty(o)) {
            Map<String, Object> bean2Map = BeanUtil.bean2Map(o);
            for (String key : bean2Map.keySet()) {
                if (Assert.isEmpty(bean2Map.get(key))) {
                    continue;
                }
                wrapper.eq(VariableNameUtils.humpToLine(key), bean2Map.get(key));
            }
        }
        return medicineDao.selectList(wrapper);
    }

    @Override
    public List<Medicine> all() {
        return query(null);
    }

    // 添加药品信息
    @Override
    public Medicine save(Medicine o) throws IOException {
        if (Assert.isEmpty(o.getId())) {
            medicineDao.insert(o);
            //在es中添加药品信息
            esService.AddMediniceByname(o.getMedicineName());

        } else {
            // 先在数据库里面更新数据
          medicineDao.updateById(o);
            // 在es中更新药品信息
            String ID = o.getId().toString();
            esService.updateMedicineById(ID);
        }
        return medicineDao.selectById(o.getId());
    }

    // 根据id查询
    @Override
    public Medicine get(Serializable id) {
        return medicineDao.selectById(id);
    }

    // 删除药品
    @Override
    public int delete(Serializable id) throws IOException {
        String ID = id.toString();
        //删除es里面的数据
        esService.DeleteMedicineById(ID);
        //删除数据库里面的数据
        return medicineDao.deleteById(id);
    }

    //  查询(搜索框搜索)
    public Map<String, Object> getMedicineList(String nameValue, Integer page) {

        List<Medicine> medicineList = null;
        Map<String, Object> map = new HashMap<>(4);
        if (Assert.notEmpty(nameValue)) {
            medicineList = medicineDao.selectList(new QueryWrapper<Medicine>().
                    like("medicine_name", nameValue)
                    .or().like("keyword", nameValue)
                    .or().like("medicine_effect", nameValue)
                    .last("limit " + (page - 1) * 9 + "," + page * 9));
        } else {
            medicineList = medicineDao.selectList(new QueryWrapper<Medicine>()
                    .last("limit " + (page - 1) * 9 + "," + page * 9));
        }
        map.put("medicineList", medicineList);
        map.put("size", medicineList.size() < 9 ? 1 : medicineList.size() / 9 + 1);
        return map;

    }


    //    高亮
    public List<MedicineDoc> EsHighlight(String key) throws IOException {
        List<MedicineDoc> medicineDoc = testHighlight(key);
        return medicineDoc;
    }

    // 高亮搜索
    List<MedicineDoc> testHighlight(String searchKeyword) throws IOException {
        // 1.准备Request请求
        SearchRequest request = new SearchRequest("medicine");
        // 2.1 query
//        request.source().query(QueryBuilders.matchQuery("medicine_name", searchKeyword));
//        // 2.2 高亮
//        request.source().highlighter(new HighlightBuilder().field("medicine_name").requireFieldMatch(false));
        request.source(new SearchSourceBuilder()
                .query(QueryBuilders.multiMatchQuery(searchKeyword, "medicineName", "medicineEffect"))
                .highlighter(new HighlightBuilder().field("medicineName").field("medicineEffect").requireFieldMatch(false))
        );

        // 3.发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        // 4.解析响应
        List<MedicineDoc> medicineDoc = highlightResponse(response);
        return medicineDoc;
    }

    //解析响应
//    private List<MedicineDoc> highlightResponse(SearchResponse response) {
//        SearchHits searchHits = response.getHits();
//        SearchHit[] hits = searchHits.getHits();
//        long total = searchHits.getTotalHits().value;
//        System.out.println("总共搜索到：" + total + "条数据");
//        List<MedicineDoc> medicineDocList = new ArrayList<>();
//
//        for (SearchHit hit : hits) {
//            String json = hit.getSourceAsString();
//            MedicineDoc medicineDoc = JSON.parseObject(json, MedicineDoc.class);
//
//            //获取高亮结果
//            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
//            if (!CollectionUtils.isEmpty(highlightFields)) {
//                //根据字段名获取高亮结果
//                HighlightField highlightField = highlightFields.get("medicineName");
//                HighlightField highlightEffect = highlightFields.get("medicineEffect");
//                if (highlightField != null) {
//                    String name = highlightField.getFragments()[0].string();
//                    String effect = highlightEffect.getFragments()[0].string();
//
//                    //覆盖非高亮结果
//                    medicineDoc.setMedicineName(name);
//                    medicineDoc.setMedicineEffect(effect);
//                }
//            }
//
//            medicineDocList.add(medicineDoc);
//        }
//        return medicineDocList;
//    }
    private List<MedicineDoc> highlightResponse(SearchResponse response) {
        SearchHits searchHits = response.getHits();
        SearchHit[] hits = searchHits.getHits();
        long total = searchHits.getTotalHits().value;
        System.out.println("总共搜索到：" + total + "条数据");
        List<MedicineDoc> medicineDocList = new ArrayList<>();

        for (SearchHit hit : hits) {
            String json = hit.getSourceAsString();
            MedicineDoc medicineDoc = JSON.parseObject(json, MedicineDoc.class);

            //获取高亮结果
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            if (!CollectionUtils.isEmpty(highlightFields)) {
                //根据字段名获取高亮结果
                HighlightField highlightField = highlightFields.get("medicineName");
                HighlightField highlightEffect = highlightFields.get("medicineEffect");
                if (highlightField != null) {
                    String name = highlightField.getFragments()[0].string();
                    //覆盖非高亮结果
                    medicineDoc.setMedicineName(name);
                }
                if (highlightEffect != null) {
                    String effect = highlightEffect.getFragments()[0].string();
                    //覆盖非高亮结果
                    medicineDoc.setMedicineEffect(effect);
                }
            }

            medicineDocList.add(medicineDoc);
        }
        return medicineDocList;
    }



}